package ui.clustering;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Paint;
import java.awt.Shape;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map.Entry;

import javax.swing.JPanel;

import org.apache.commons.collections.Predicate;

import utils.CategoriesInfo;

import edu.uci.ics.jung.graph.ArchetypeVertex;
import edu.uci.ics.jung.graph.Vertex;
import edu.uci.ics.jung.graph.decorators.DefaultToolTipFunction;
import edu.uci.ics.jung.graph.decorators.EdgeShape;
import edu.uci.ics.jung.graph.decorators.VertexPaintFunction;
import edu.uci.ics.jung.graph.decorators.VertexShapeFunction;
import edu.uci.ics.jung.graph.decorators.VertexStringer;
import edu.uci.ics.jung.graph.impl.SparseGraph;
import edu.uci.ics.jung.visualization.FRLayout;
import edu.uci.ics.jung.visualization.GraphZoomScrollPane;
import edu.uci.ics.jung.visualization.Layout;
import edu.uci.ics.jung.visualization.PluggableRenderer;
import edu.uci.ics.jung.visualization.ShapePickSupport;
import edu.uci.ics.jung.visualization.SpringLayout;
import edu.uci.ics.jung.visualization.StaticLayout;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.contrib.CircleLayout;
import edu.uci.ics.jung.visualization.contrib.KKLayout;
import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
import edu.uci.ics.jung.visualization.control.ModalGraphMouse;
import edu.uci.ics.jung.visualization.control.ModalGraphMouse.Mode;

@SuppressWarnings("unused")
public class ClusteringGraph extends SparseGraph implements VertexStringer,
        VertexPaintFunction, VertexShapeFunction, Predicate
{
    private ClusteringGraph(CategoriesInfo ci)
    {
        for (Entry<String, HashSet<String>> entry : ci.getCategoriesMap()
                .entrySet())
        {
            String center = entry.getKey();
            ArrayList<String> context = new ArrayList<String>();
            context.addAll(entry.getValue());
            ClusterVertex vertex = new ClusterVertex(center, context);
            this.addVertex(vertex);
        }
    }

    public static JPanel createVisualizationViewer(VisClusteringInfo vci,
            Dimension size)
    {
        final ClusteringGraph cg = new ClusteringGraph(vci.getCategoriesInfo());
        final VisualizationViewer vv = cg.getVisualizationViewer(size, vci
                .getCoordinateInfo());
        final JPanel jpanel = new JPanel();
        jpanel.setLayout(new BorderLayout());
        final GraphZoomScrollPane panel = new GraphZoomScrollPane(vv);
        jpanel.add(panel, BorderLayout.CENTER);
        return jpanel;
    }

    private VisualizationViewer getVisualizationViewer(Dimension size,
            HashMap<String, double[]> coordinateInfo)
    {
        VisualizationViewer vv = this.getVisualizationViewer(coordinateInfo);
        vv.setSize(size);
        return vv;
    }

    private VisualizationViewer getVisualizationViewer(
            HashMap<String, double[]> coordinateInfo)
    {
        PluggableRenderer pr = new PluggableRenderer();
        Layout layout = new CoordinateLayout(this, coordinateInfo);
        // Layout layout = new CircleLayout(this);
        VisualizationViewer vv = new VisualizationViewer(layout, pr);
        pr.setVertexStringer(this);
        pr.setVertexPaintFunction(this);
        pr.setVertexShapeFunction(this);
        pr.setEdgeIncludePredicate(this);
        vv.setPickSupport(new ShapePickSupport());
        vv.setBackground(Color.white);
        vv.setToolTipFunction(new DefaultToolTipFunction());
        final ModalGraphMouse gm = new DefaultModalGraphMouse();
        vv.setGraphMouse(gm);
        gm.setMode(Mode.PICKING);
        return vv;
    }

    @Override
    public String getLabel(ArchetypeVertex v)
    {
        return ((ClusterVertex) v).getInfo();
    }

    @Override
    public Paint getDrawPaint(Vertex v)
    {
        return ((ClusterVertex) v).getDrawPaint();
    }

    @Override
    public Paint getFillPaint(Vertex v)
    {
        return ((ClusterVertex) v).getFillPaint();
    }

    @Override
    public Shape getShape(Vertex v)
    {
        return ((ClusterVertex) v).getShape();
    }

    @Override
    public boolean evaluate(Object arg0)
    {
        // TODO Auto-generated method stub
        return false;
    }

}
